home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / xulrunner-1.9.0.14 / chrome / pippki.jar / content / pippki / exceptionDialog.js < prev    next >
Encoding:
JavaScript  |  2008-04-22  |  11.0 KB  |  358 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is mozilla.org code.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Mozilla Corporation.
  18.  * Portions created by the Initial Developer are Copyright (C) 2007
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Contributor(s):
  22.  *   Johnathan Nightingale <johnath@mozilla.com>
  23.  *
  24.  * Alternatively, the contents of this file may be used under the terms of
  25.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  26.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  27.  * in which case the provisions of the GPL or the LGPL are applicable instead
  28.  * of those above. If you wish to allow use of your version of this file only
  29.  * under the terms of either the GPL or the LGPL, and not to allow others to
  30.  * use your version of this file under the terms of the MPL, indicate your
  31.  * decision by deleting the provisions above and replace them with the notice
  32.  * and other provisions required by the GPL or the LGPL. If you do not delete
  33.  * the provisions above, a recipient may use your version of this file under
  34.  * the terms of any one of the MPL, the GPL or the LGPL.
  35.  *
  36.  * ***** END LICENSE BLOCK ***** */
  37.  
  38.  
  39. var gDialog;
  40. var gBundleBrand;
  41. var gPKIBundle;
  42. var gSSLStatus;
  43. var gCert;
  44. var gChecking;
  45. var gBroken;
  46. var gNeedReset;
  47.  
  48. function badCertListener() {}
  49. badCertListener.prototype = {
  50.   getInterface: function (aIID) {
  51.     return this.QueryInterface(aIID);
  52.   },
  53.   QueryInterface: function(aIID) {
  54.     if (aIID.equals(Components.interfaces.nsIBadCertListener2) ||
  55.         aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
  56.         aIID.equals(Components.interfaces.nsISupports))
  57.       return this;
  58.  
  59.     throw Components.results.NS_ERROR_NO_INTERFACE;
  60.   },  
  61.   handle_test_result: function () {
  62.     if (gSSLStatus)
  63.       gCert = gSSLStatus.QueryInterface(Components.interfaces.nsISSLStatus).serverCert;
  64.   },
  65.   notifyCertProblem: function MSR_notifyCertProblem(socketInfo, sslStatus, targetHost) {
  66.     gBroken = true;
  67.     gSSLStatus = sslStatus;
  68.     this.handle_test_result();
  69.     return true; // suppress error UI
  70.   }
  71. }
  72.  
  73. function initExceptionDialog() {
  74.   gNeedReset = false;
  75.   gDialog = document.documentElement;
  76.   gBundleBrand = srGetStrBundle("chrome://branding/locale/brand.properties");
  77.   gPKIBundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
  78.  
  79.   var brandName = gBundleBrand.GetStringFromName("brandShortName");
  80.   
  81.   setText("warningText", gPKIBundle.formatStringFromName("addExceptionBrandedWarning2",
  82.                                                          [brandName], 1));
  83.   gDialog.getButton("extra1").disabled = true;
  84.   
  85.   var args = window.arguments;
  86.   if (args && args[0]) {
  87.     if (args[0].location) {
  88.       // We were pre-seeded with a location.
  89.       document.getElementById("locationTextBox").value = args[0].location;
  90.       document.getElementById('checkCertButton').disabled = false;
  91.       
  92.       // We can optionally pre-fetch the certificate too
  93.       if (args[0].prefetchCert)
  94.         checkCert();
  95.     }
  96.     
  97.     // Set out parameter to false by default
  98.     args[0].exceptionAdded = false; 
  99.   }
  100. }
  101.  
  102. // returns true if found and global status could be set
  103. function findRecentBadCert(uri) {
  104.   try {
  105.     var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"]
  106.                          .getService(Components.interfaces.nsIRecentBadCertsService);
  107.     if (!recentCertsSvc)
  108.       return false;
  109.  
  110.     var hostWithPort = uri.host + ":" + uri.port;
  111.     gSSLStatus = recentCertsSvc.getRecentBadCert(hostWithPort);
  112.     if (!gSSLStatus)
  113.       return false;
  114.  
  115.     gCert = gSSLStatus.QueryInterface(Components.interfaces.nsISSLStatus).serverCert;
  116.     if (!gCert)
  117.       return false;
  118.  
  119.     gBroken = true;
  120.   }
  121.   catch (e) {
  122.     return false;
  123.   }
  124.   updateCertStatus();  
  125.   return true;
  126. }
  127.  
  128. /**
  129.  * Attempt to download the certificate for the location specified, and populate
  130.  * the Certificate Status section with the result.
  131.  */
  132. function checkCert() {
  133.   
  134.   gCert = null;
  135.   gSSLStatus = null;
  136.   gChecking = true;
  137.   gBroken = false;
  138.   updateCertStatus();
  139.  
  140.   var uri = getURI();
  141.  
  142.   // Is the cert already known in the list of recently seen bad certs?
  143.   if (findRecentBadCert(uri) == true)
  144.     return;
  145.  
  146.   var req = new XMLHttpRequest();
  147.   try {
  148.     if(uri) {
  149.       req.open('GET', uri.prePath, false);
  150.       req.channel.notificationCallbacks = new badCertListener();
  151.       req.send(null);
  152.     }
  153.   } catch (e) {
  154.     // We *expect* exceptions if there are problems with the certificate
  155.     // presented by the site.  Log it, just in case, but we can proceed here,
  156.     // with appropriate sanity checks
  157.     Components.utils.reportError("Attempted to connect to a site with a bad certificate in the add exception dialog. " +
  158.                                  "This results in a (mostly harmless) exception being thrown. " +
  159.                                  "Logged for information purposes only: " + e);
  160.   } finally {
  161.     gChecking = false;
  162.   }
  163.       
  164.   if(req.channel && req.channel.securityInfo) {
  165.     const Ci = Components.interfaces;
  166.     gSSLStatus = req.channel.securityInfo
  167.                     .QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
  168.     gCert = gSSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
  169.   }
  170.   updateCertStatus();  
  171. }
  172.  
  173. /**
  174.  * Build and return a URI, based on the information supplied in the
  175.  * Certificate Location fields
  176.  */
  177. function getURI() {
  178.   // Use fixup service instead of just ioservice's newURI since it's quite likely
  179.   // that the host will be supplied without a protocol prefix, resulting in malformed
  180.   // uri exceptions being thrown.
  181.   var fus = Components.classes["@mozilla.org/docshell/urifixup;1"]
  182.                       .getService(Components.interfaces.nsIURIFixup);
  183.   var uri = fus.createFixupURI(document.getElementById("locationTextBox").value, 0);
  184.   
  185.   if(!uri)
  186.     return null;
  187.  
  188.   if(uri.scheme == "http")
  189.     uri.scheme = "https";
  190.  
  191.   if (uri.port == -1)
  192.     uri.port = 443;
  193.  
  194.   return uri;
  195. }
  196.  
  197. function resetDialog() {
  198.   document.getElementById("viewCertButton").disabled = true;
  199.   document.getElementById("permanent").disabled = true;
  200.   gDialog.getButton("extra1").disabled = true;
  201.   setText("headerDescription", "");
  202.   setText("statusDescription", "");
  203.   setText("statusLongDescription", "");
  204.   setText("status2Description", "");
  205.   setText("status2LongDescription", "");
  206.   setText("status3Description", "");
  207.   setText("status3LongDescription", "");
  208. }
  209.  
  210. /**
  211.  * Called by input textboxes to manage UI state
  212.  */
  213. function handleTextChange() {
  214.   var checkCertButton = document.getElementById('checkCertButton');
  215.   checkCertButton.disabled = !(document.getElementById("locationTextBox").value);
  216.   if (gNeedReset) {
  217.     gNeedReset = false;
  218.     resetDialog();
  219.   }
  220. }
  221.  
  222. function updateCertStatus() {
  223.   var shortDesc, longDesc;
  224.   var shortDesc2, longDesc2;
  225.   var shortDesc3, longDesc3;
  226.   var use2 = false;
  227.   var use3 = false;
  228.   if(gCert) {
  229.     if(gBroken) { 
  230.       var mms = "addExceptionDomainMismatchShort";
  231.       var mml = "addExceptionDomainMismatchLong";
  232.       var exs = "addExceptionExpiredShort";
  233.       var exl = "addExceptionExpiredLong";
  234.       var uts = "addExceptionUnverifiedShort";
  235.       var utl = "addExceptionUnverifiedLong";
  236.       var use1 = false;
  237.       if (gSSLStatus.isDomainMismatch) {
  238.         use1 = true;
  239.         shortDesc = mms;
  240.         longDesc  = mml;
  241.       }
  242.       if (gSSLStatus.isNotValidAtThisTime) {
  243.         if (!use1) {
  244.           use1 = true;
  245.           shortDesc = exs;
  246.           longDesc  = exl;
  247.         }
  248.         else {
  249.           use2 = true;
  250.           shortDesc2 = exs;
  251.           longDesc2  = exl;
  252.         }
  253.       }
  254.       if (gSSLStatus.isUntrusted) {
  255.         if (!use1) {
  256.           use1 = true;
  257.           shortDesc = uts;
  258.           longDesc  = utl;
  259.         }
  260.         else if (!use2) {
  261.           use2 = true;
  262.           shortDesc2 = uts;
  263.           longDesc2  = utl;
  264.         } 
  265.         else {
  266.           use3 = true;
  267.           shortDesc3 = uts;
  268.           longDesc3  = utl;
  269.         }
  270.       }
  271.       
  272.       // In these cases, we do want to enable the "Add Exception" button
  273.       gDialog.getButton("extra1").disabled = false;
  274.       document.getElementById("permanent").disabled = false;
  275.       setText("headerDescription", gPKIBundle.GetStringFromName("addExceptionInvalidHeader"));
  276.     }
  277.     else {
  278.       shortDesc = "addExceptionValidShort";
  279.       longDesc  = "addExceptionValidLong";
  280.       gDialog.getButton("extra1").disabled = true;
  281.       document.getElementById("permanent").disabled = true;
  282.     }
  283.     
  284.     document.getElementById("viewCertButton").disabled = false;
  285.   }
  286.   else if (gChecking) {
  287.     shortDesc = "addExceptionCheckingShort";
  288.     longDesc  = "addExceptionCheckingLong";
  289.     document.getElementById("viewCertButton").disabled = true;
  290.     gDialog.getButton("extra1").disabled = true;
  291.     document.getElementById("permanent").disabled = true;
  292.   }
  293.   else {
  294.     shortDesc = "addExceptionNoCertShort";
  295.     longDesc  = "addExceptionNoCertLong";
  296.     document.getElementById("viewCertButton").disabled = true;
  297.     gDialog.getButton("extra1").disabled = true;
  298.     document.getElementById("permanent").disabled = true;
  299.   }
  300.   
  301.   setText("statusDescription", gPKIBundle.GetStringFromName(shortDesc));
  302.   setText("statusLongDescription", gPKIBundle.GetStringFromName(longDesc));
  303.  
  304.   if (use2) {
  305.     setText("status2Description", gPKIBundle.GetStringFromName(shortDesc2));
  306.     setText("status2LongDescription", gPKIBundle.GetStringFromName(longDesc2));
  307.   }
  308.  
  309.   if (use3) {
  310.     setText("status3Description", gPKIBundle.GetStringFromName(shortDesc3));
  311.     setText("status3LongDescription", gPKIBundle.GetStringFromName(longDesc3));
  312.   }
  313.  
  314.   gNeedReset = true;
  315. }
  316.  
  317. /**
  318.  * Handle user request to display certificate details
  319.  */
  320. function viewCertButtonClick() {
  321.   if (gCert)
  322.     viewCertHelper(this, gCert);
  323.     
  324. }
  325.  
  326. /**
  327.  * Handle user request to add an exception for the specified cert
  328.  */
  329. function addException() {
  330.   if(!gCert || !gSSLStatus)
  331.     return;
  332.  
  333.   var overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
  334.                                   .getService(Components.interfaces.nsICertOverrideService);
  335.   var flags = 0;
  336.   if(gSSLStatus.isUntrusted)
  337.     flags |= overrideService.ERROR_UNTRUSTED;
  338.   if(gSSLStatus.isDomainMismatch)
  339.     flags |= overrideService.ERROR_MISMATCH;
  340.   if(gSSLStatus.isNotValidAtThisTime)
  341.     flags |= overrideService.ERROR_TIME;
  342.   
  343.   var permanentCheckbox = document.getElementById("permanent");
  344.  
  345.   var uri = getURI();
  346.   overrideService.rememberValidityOverride(
  347.     uri.asciiHost, uri.port,
  348.     gCert,
  349.     flags,
  350.     !permanentCheckbox.checked);
  351.   
  352.   var args = window.arguments;
  353.   if (args && args[0])
  354.     args[0].exceptionAdded = true;
  355.   
  356.   gDialog.acceptDialog();
  357. }
  358.